""""""
"""
______________________________
time：2021/5/28
______________________________
封装一个用来读取Excel的类；
"""

import os
import openpyxl

from scripts.handle_yaml import do_yaml
from scripts.handle_path import DATAS_DIR


class CaseData:
    """测试用例数据类，专门用来创建对象存放用例数据的"""
    # 里面什么代码都不用写，只需要定义在这就行
    pass


class ReadExcel(object):
    # 痛点：每调一个接口都需拼接一次路径很繁琐；
    # 优化为：指定一个默认读取的文件名，如果使用时有传filename，则用传的；如果没传用默认的
    def __init__(self, sheetname, filename=None):
        if filename is None:
            self.filename = os.path.join(DATAS_DIR, do_yaml.read_yaml("excel", "cases_path"))
        else:
            self.filename = filename
        self.sheetname = sheetname

    def open(self):
        """打开工作簿和表单"""
        self.workbook = openpyxl.load_workbook(self.filename)
        self.sheet = self.workbook[self.sheetname]

    def read_data(self):
        """从Excel中读取数据的方法,，数据返回的格式：嵌套字典的列表"""
        # 打开文件和表单
        self.open()
        # 将表格中的数据按行读取出来，每一行放到一个元组里面，读取出来的是表格对象
        rows = list(self.sheet.rows)
        # 创建一个空列表，用来存放所有的测试数据
        finally_testcases = []

        # 获取表头，放到一个列表中
        title = []
        for c in rows[0]:
            title.append(c.value)

        # 获取除表头以外的其他行的数据
        for r in rows[1:]:
            # 每遍历一行，创建一个 空列表，用来存放该行的数据
            data = []
            for c in r:
                cc=c.value
                # print("得到Excel中每个单元格中的值：",cc)
                data.append(c.value)
            print("从Excel中读取得到的data：", data)
            # 将表头和该行的数据进行聚合打包，转换为字典
            case_data = dict(zip(title, data))
            # 将该行的用例数据加入到最终的列表中
            finally_testcases.append(case_data)
        # 一定要关闭工作簿
        self.workbook.close()
        # 将读取的数据进行返回
        return finally_testcases

    def read_data_to_object(self):
        """读取数据的方法，数据返回的格式：嵌套对象的列表"""
        """
           从Excel中读取数据，并转换为对象的格式 ，这个之后会常用到;
           注意：用这种方法时，在Excel中编写测试用例不能有空行空列，如果有，在会认为是none，设置数据值时会报错
        """
        # 1.打开文件和表单
        self.open()
        # 2.将表单中的内容按行获取所有的格子
        rows = list(self.sheet.rows)
        # 3.创建一个空列表，用来存放所有的测试数据
        finally_testcases = []
        """
               data=[]
               for i in range(5):
                   data.append('data{}'.format(i))
               优化：列表推导式 ,把三行代码用一行表示出来
               data1=['data{}'.format(i) for i in range(5)]        
        """
        # 4.通过列表推导式获取Excel表头，放到一个列表中
        """
        title = []
        for c in rows[0]:
            title.append(c.value)
        代码优化：列表推导式写为1行；
        """
        title = [c.value for c in rows[0]]
        # 5.获取Excel中除表头以外的其他行数据，列表推导式优化代码
        for r in rows[1:]:
            data = [c.value for c in r]
            """
             # item = list(zip(title, data))
             # print(item)
             优化为下面直接在遍历zip对象
             """
            # 5.1创建一个用例数据对象
            caseobj = CaseData()
            # 5.2将表头和该行数据进行聚合打包[得到的元组]直接遍历
            for i in zip(title, data):  # zip对象为可迭代对象，可以直接遍历的不需要再转化为list再去遍历
                # 通过反射机制，将表头设为对象的实例属性，对应值设为对象的属性值
                setattr(caseobj, i[0], i[1])
                # 5.3将该行的用例数据加入到最终的列表中
            finally_testcases.append(caseobj)
        # 6.一定要关闭工作簿对象
        self.workbook.close()
        # 7.将读取的数据进行返回:嵌套对象的列表
        return finally_testcases

    def write_data(self, row, column, value):

        """写入数据的方法:回写测试结果"""
        # 1.打开工作簿和表单
        self.open()
        # 2.写入内容
        self.sheet.cell(row=row, column=column, value=value)
        # 3.保存文件
        self.workbook.save(self.filename)
        # 4.关闭工作簿对象
        self.workbook.close()


if __name__ == '__main__':
    pass
    read = ReadExcel('supplier')
    data = read.read_data()
    # data = read.read_data_to_object()
    print(data)
    # read.write_data(2, 8, '通过')
    # read.write_data(3, 8, '不通过')
